package io.github.wslxm.springbootplus2.core.utils;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import io.github.wslxm.springbootplus2.core.base.model.BasePage;
import io.github.wslxm.springbootplus2.core.result.Result;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 请求统一封装
 *
 * @author ws
 * @mail 1720696548@qq.com
 * @date 2020/4/24 0024 9:54
 * @return
 */
@Slf4j
public class XjHttpUtil {


    /**
     * 设置请求超时时间
     */
    private static final int defaultTimeout = 5 * 1000;

    /**
     * get 请求 (单对象/参数数据)
     * @param url 请求地址
     * @param headers 请求头数据
     * @param params 请求参数
     * @param tClass 响应数据 Result<T> 中的 T.calss
     */
    public static <T> Result<T> get(String url, Map<String, String> headers, Map<String, Object> params, Class<T> tClass) {
        Result<T> result = null;
        try {
            String resultStr = HttpRequest.get(url).addHeaders(headers).timeout(defaultTimeout).form(params).execute().body();
            result = JSON.parseObject(resultStr, Result.class);
        } catch (IORuntimeException e) {
            result = Result.errorNoI18n(500, url + " http request timed out");
        } catch (Exception e) {
            result = Result.errorNoI18n(500, url + " http request error -> " + url);
        }
        // 内部数据 json对象 装换为 返回对象
        if (result.getCode().equals(HttpStatus.HTTP_OK) && result.getData() != null) {
            result.setData(JSON.parseObject(JSON.toJSONString(result.getData()), tClass));
        }
        return result;
    }

    /**
     * get 请求 (列表数据)
     * @author wangsong
     * @param url 请求地址
     * @param headers 请求头数据
     * @param params 请求参数
     * @param tClass 响应数据 Result<List<T>> 中的 T.calss
     * @mail 1720696548@qq.com
     * @date 2022/11/2 0002 10:50
     * @version 1.0.0
     */
    public static <T> Result<List<T>> getList(String url, Map<String, String> headers, Map<String, Object> params, Class<T> tClass) {
        Result<List<T>> result = null;
        try {
            String resultStr = HttpRequest.get(url).addHeaders(headers).timeout(defaultTimeout).form(params).execute().body();
            // 内部数据 json对象 装换为 返回对象
            result = JSON.parseObject(resultStr, Result.class);
            if (result.getCode().equals(HttpStatus.HTTP_OK) && result.getData() != null) {
                result.setData(JSON.parseArray(JSON.toJSONString(result.getData()), tClass));
            }
        } catch (IORuntimeException e) {
            result = Result.errorNoI18n(500, url + " http request timed out");
        } catch (Exception e) {
            result = Result.errorNoI18n(500, url + " http request error -> " + url);
        }
        return result;
    }


    /**
     * get 请求 (分页数据)
     * @author wangsong
     * @param url 请求地址
     * @param headers 请求头数据
     * @param params 请求参数
     * @param tClass 响应数据 Result<BasePage<T>> 中的 T.calss
     * @mail 1720696548@qq.com
     * @date 2022/11/2 0002 10:50
     * @version 1.0.0
     */
    public static <T> Result<BasePage<T>> getPage(String url, Map<String, String> headers, Map<String, Object> params, Class<T> tClass) {
        Result<BasePage<T>> result = null;
        try {
            String resultStr = HttpRequest.get(url).addHeaders(headers).timeout(defaultTimeout).form(params).execute().body();
            result = JSON.parseObject(resultStr, Result.class);
            // 内部数据 json对象 装换为 返回对象
            if (result.getCode().equals(HttpStatus.HTTP_OK) && result.getData() != null) {
                BasePage page = JSON.parseObject(JSON.toJSONString(result.getData()), BasePage.class);
                if (!page.getRecords().isEmpty()) {
                    page.setRecords(JSON.parseArray(JSON.toJSONString(page.getRecords()), tClass));
                }
                result.setData(page);
            }
        } catch (IORuntimeException e) {
            result = Result.errorNoI18n(500, url + " http request timed out");
        } catch (Exception e) {
            result = Result.errorNoI18n(500, url + " http request error -> " + url);
        }
        return result;
    }

    /**
     * get 请求 (返回 map 数据)
     * @author wangsong
     * @param url 请求地址
     * @param headers 请求头数据
     * @param params 请求参数
     * @param kClass 响应数据 Result<Map<Object,V>> 中的 Object 的数据类型
     * @param tClass 响应数据 Result<Map<Object,V>> 中的 V.calss
     * @mail 1720696548@qq.com
     * @date 2022/11/2 0002 10:50
     * @version 1.0.0
     */
    public static <K, V> Result<Map<K, V>> getMap(String url, Map<String, String> headers, Map<String, Object> params, Class<K> kClass, Class<V> tClass) {
        Result<Map<K, V>> result = null;
        try {
            String resultStr = HttpRequest.get(url).addHeaders(headers).timeout(defaultTimeout).form(params).execute().body();
            result = JSON.parseObject(resultStr, Result.class);
            // 内部数据 json对象 装换为 返回对象
            if (result.getCode().equals(HttpStatus.HTTP_OK) && result.getData() != null) {
                Map map = JSON.parseObject(JSON.toJSONString(result.getData()), Map.class);
                if (map.size() > 0) {
                    Map<K, V> newMap = new HashMap<>();
                    for (Object key : map.keySet()) {
                        newMap.put((K) key, JSON.parseObject(JSON.toJSONString(map.get(key)), tClass));
                    }
                    result.setData(newMap);
                }
            }
        } catch (IORuntimeException e) {
            result = Result.errorNoI18n(500, url + " http request timed out");
        } catch (Exception e) {
            result = Result.errorNoI18n(500, url + " http request error -> " + url);
        }
        return result;
    }


    /**
     * post 请求
     * @param   url =  请求地址
     * @param   params =  query 参数(没有传null)
     * @param   d =       body 参数 (任意对象,自动转json)
     * @return
     */
    public static <D, T> Result<T> post(String url, Map<String, String> headers, Map<String, Object> params, D d, Class<T> tClass) {
        Result<T> result = null;
        try {
            String dJson = d == null ? null : JSON.toJSONString(d);
            String resultStr = HttpRequest.post(url)
                    .addHeaders(headers)
                    .timeout(defaultTimeout)
                    .form(params)
                    .body(dJson)
                    .execute().body();
            result = JSON.parseObject(resultStr, Result.class);
            // 内部数据 json对象 装换为 返回对象
            if (result.getCode().equals(HttpStatus.HTTP_OK) && result.getData() != null) {
                result.setData(JSON.parseObject(JSON.toJSONString(result.getData()), tClass));
            }
        } catch (IORuntimeException e) {
            result = Result.errorNoI18n(500, url + " http request timed out");
        } catch (Exception e) {
            result = Result.errorNoI18n(500, url + " http request error -> " + url);
        }
        return result;
    }
}
